/*
 * ngx_http_ex_memcached_module.c
 *
 *  Created on: Jan 31, 2010
 *      Author: herbert
 */

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <libmemcached/memcached.h>

#define MAX_KEY_SIZE 250
#define MAX_VALUE_SIZE 1024*1024


static char *ngx_http_ext_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd,
		void *conf);
//模块请求处理
static ngx_int_t ngx_http_ext_memcached_handler(ngx_http_request_t *request);
static u_char *memcached_cat_data();

typedef struct {
    ngx_http_upstream_conf_t   upstream;
    ngx_int_t                  index;
} ngx_http_ext_memcached_loc_conf_t;
//参数
static ngx_command_t ngx_http_ext_memcached_commands[] = {

	{   ngx_string("ext_memcached_pass"),
		NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
		ngx_http_ext_memcached_pass,
		0,
		0,
		NULL },
		ngx_null_command
};

static ngx_http_module_t ngx_http_ext_memcached_module_ctx = {
		NULL, /* preconfiguration */
		NULL, /* postconfiguration */
		NULL, /* create main configuration */
		NULL, /* init main configuration */
		NULL, /* create server configuration */
		NULL, /* merge server configuration */
		NULL, /* create location configuration */
		NULL /* merge location configuration */
};

ngx_module_t ngx_http_ext_memcached_module = {
		NGX_MODULE_V1,
		&ngx_http_ext_memcached_module_ctx, /* module context */
		ngx_http_ext_memcached_commands, /* module directives */
		NGX_HTTP_MODULE, /* module type */
		NULL, /* init master */
		NULL, /* init module */
		NULL, /* init process */
		NULL, /* init thread */
		NULL, /* exit thread */
		NULL, /* exit process */
		NULL, /* exit master */
		NGX_MODULE_V1_PADDING
};
static u_char ngx_hello_world[] = "hello world";

static ngx_int_t ngx_http_ext_memcached_handler(ngx_http_request_t *request) {
	ngx_buf_t *b;
	ngx_chain_t out;

	request->headers_out.content_type.len = sizeof("text/html") - 1;
	request->headers_out.content_type.data = (u_char *) "text/html";

	b = ngx_pcalloc(request->pool, sizeof(ngx_buf_t));

	out.buf = b;
	out.next = NULL;
	u_char *data = memcached_cat_data();
	ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,"data=%s", data);
//	printf("data=%s \n", data);
	b->pos = data;
	b->last = data + sizeof(data);
	b->memory = 1;
	b->last_buf = 1;

	request->headers_out.status = NGX_HTTP_OK;
	request->headers_out.content_length_n = sizeof(data);
	ngx_http_send_header(request);

	return ngx_http_output_filter(request, &out);
}

static char *ngx_http_ext_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd,
		void *conf) {
	ngx_http_ext_memcached_loc_conf_t *mlcf = conf;

    ngx_str_t                 *value;
    ngx_url_t                  u;
    ngx_http_core_loc_conf_t  *clcf;

    if (mlcf->upstream.upstream) {
        return "is duplicate";
    }

    value = cf->args->elts;

    ngx_memzero(&u, sizeof(ngx_url_t));

    u.url = value[1];
    u.no_resolve = 1;

    mlcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
    if (mlcf->upstream.upstream == NULL) {
        return NGX_CONF_ERROR;
    }

    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
//    printf("index=%d\n",mlcf->index);

	clcf->handler = ngx_http_ext_memcached_handler;

    if (clcf->name.data[clcf->name.len - 1] == '/') {
        clcf->auto_redirect = 1;
    }

//    mlcf->index = ngx_http_get_variable_index(cf, &ngx_http_memcached_key);

//    if (mlcf->index == NGX_ERROR) {
//        return NGX_CONF_ERROR;
//    }

    return NGX_CONF_OK;
}

static u_char *memcached_cat_data(){
    memcached_st *memc;
    uint32_t  flags;
    memcached_return rc;
    memcached_server_st *servers;
    memc= memcached_create(NULL);

    servers= memcached_servers_parse("127.0.0.1:11211");
    memcached_server_push(memc, servers);
    memcached_server_list_free(servers);
    memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 0);

    char *key = "data";
    u_char *return_value;
    size_t return_value_length;
    return_value= memcached_get(memc, key, sizeof(key),
                                              &return_value_length, &flags, &rc);

    printf("memcached_get key=%s value=%s \n", key, return_value);
//    free(return_value);
//    memcached_free(memc);
    return return_value;
}
